#ifndef CPerlinNoise_____
#define CPerlinNoise_____

#include "Vector2f.h"
#include "Vector3f.h"

#define WRAP_INDEX	256
#define MOD_MASK	255
#define MAX			4096


/*	Definition of Terms: (cf. Matt Zucker; Ken Perlin)

	Noise Function: a function that takes a coordinate in some space and maps
	it to a real number between -1 and 1 (or between 0 and 1).

	Wavelet: a functions which drops off to zero outside of some region, and
	which integrates to zero. The radius of a wavelet simply refers to the
	distance in its domain space from the wavelet center to where its value
	drops off to zero.

	Perlin Noise: a function for generating coherent noise over a space. Coherent
	noise means that for any two points in the space, the value of the noise
	function changes smoothly as you move from one point to the other--no 
	discontinuities. The key to understanding the algorithm is to think of
	space as being divided into a regular lattice of cubical cels, with one
	pseudorandom wavelet per lattice point. 

*/

//-----------------------------------------------------------------------------
class CPerlinNoise
//-----------------------------------------------------------------------------
{
  public:

	//-------------------------------------------------------------------------
	// members
	//-------------------------------------------------------------------------

	bool		m_bInitialized;
    unsigned	m_iPermutation[WRAP_INDEX * 2 + 2];		// lattice table
    float		m_fGradient1D[WRAP_INDEX * 2 + 2];		// gradient tables
    vector2f	m_fGradient2D[WRAP_INDEX * 2 + 2];
    vector3f	m_fGradient3D[WRAP_INDEX * 2 + 2];

	//-------------------------------------------------------------------------
	// member functions
	//-------------------------------------------------------------------------

    float	RandomPNFloat();			// range [-1,1]
    void	GenerateLookupTables();
	void	ReSeed();
	float	SCurve(float t);
	float	LinearInterpolation(float t, float a, float b);
	void	ComputeDistanceToLatticePoints(float x, int &grid_point1, int &grid_point2, float &distance_to_gp1, float &distance_to_gp2);
	float	PNoise1D(float x);
	float	PNoise2D(vector2f vec2f);
	float	PNoise3D(vector3f vec3f);

	//-------------------------------------------------------------------------
	// constructors
	//-------------------------------------------------------------------------
	
	CPerlinNoise();

	//-------------------------------------------------------------------------
	// constructors
	//-------------------------------------------------------------------------

	~CPerlinNoise();

};

#endif
